package com.starkuz.controllers.sites;

import com.starkuz.dao.ifaces.OrderDao;
import com.starkuz.dao.ifaces.UserDao;
import com.starkuz.dao.ifaces.sites.OrderSiteDao;
import com.starkuz.dao.ifaces.visits.VisitCtrDao;
import com.starkuz.dao.ifaces.visits.VisitOrderDao;
import com.starkuz.dto.FormFieldsDto;
import com.starkuz.dto.SetPeriodDto;
import com.starkuz.mailsender.OrderNotification;
import com.starkuz.model.Order;
import com.starkuz.model.User;
import com.starkuz.model.sites.OrderSite;
import com.starkuz.tools.StyleCleanerJSOUP;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.io.IOException;
import java.util.Collection;
import java.util.Map;
import java.util.TreeSet;


@Controller
public class OrderSitesController {

    @Autowired
    private OrderDao orderDao;

    public void setOrderDao(OrderDao orderDao) {
        this.orderDao = orderDao;
    }

    @Autowired
    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    @Autowired
    private OrderSiteDao orderSiteDao;

    public void setOrderSiteDao(OrderSiteDao orderSiteDao) {
        this.orderSiteDao = orderSiteDao;
    }

    @Autowired
    private VisitOrderDao visitOrderDao;

    public void setVisitOrderDao(VisitOrderDao visitOrderDao) {
        this.visitOrderDao = visitOrderDao;
    }

    // для шаблонов рассылки - вывод формы редактирования
    @RequestMapping(value = "/edit_order_site.html", method = RequestMethod.GET)
    public String editOrderSite(HttpServletRequest req, Order order, @RequestParam(value = "id",
            required = false) Integer idOrderSite, Map model) {
        if(!isActiveUser(req)){
            return "redirect:index.html";
        }
        OrderSite orderSite = orderSiteDao.findOrderSiteById(idOrderSite);
        if (orderSite == null) {
            model.put("cause", "Данная страница недоступна.");
            return "error";
        }
        FormFieldsDto dto = convertOrderSiteToDto(orderSite);
        model.put("formField", dto);
        model.put("order", order);
        return "order_edit";
    }


    // для шаблонов рассылки - считывание данных с формы редактирования и обработка
    @RequestMapping(value = "/edit_order_site.html", method = RequestMethod.POST)
    public String editOrderSite(@Valid FormFieldsDto dto, Order order, HttpServletRequest req, Map model) throws IOException {
        HttpSession session = req.getSession();
        String err = validateCreateOrderSite(dto);
        if (err != null) {                            //валидация
            model.put("cause", err);
            return "error";
        }
        dto = cleanForm(dto);     //todo: а надо ли тут чистить форму??? Надо подумать
        req.getSession().setAttribute("formZip", dto);
        req.getSession().setAttribute("tempOrderSiteDto", dto);
        OrderSite orderSite = convertDtoToOrderSite(dto);
        if (orderSite.getId() != null) {    //если сайту присвоен айди в БД - обновляем
            syncOrderDtoWithDB(dto);
        } else {
            session.setAttribute("tempOrderSiteDto", dto);
        }
        model.put("formField", dto);
        return "templ_order";
    }


    // для шаблонов рассылки - вывод формы создания
    @RequestMapping(value = "/create_order_site.html", method = RequestMethod.GET)
    public String createOrderSite(FormFieldsDto dto, HttpServletRequest req,
                              @RequestParam(value = "id", required = false) Integer idTemplate, Map model) {
        if(!isActiveUser(req)){
            return "redirect:index.html";
        }
        HttpSession session = req.getSession();
        if (idTemplate != null) { //при выборе шаблона из списка
            dto.setIdTemplate(idTemplate);
            model.put("formField", dto);
            return "order_edit";
        } else {  //при неявном возврате на страницу редактирования
            FormFieldsDto tempOrderSiteDto = (FormFieldsDto) session.getAttribute("tempOrderSiteDto");
            if (tempOrderSiteDto != null) {
                model.put("formField", tempOrderSiteDto);
                return "order_edit";
            } else {
                return "error";
            }
        }
    }


    //очистка dto от чужих стилей
    private FormFieldsDto cleanForm(FormFieldsDto dto) {
        String tags = dto.getFormCode();
        String action = StyleCleanerJSOUP.getAction(tags);
        String inputs = StyleCleanerJSOUP.getInputs(tags);
        dto.setInputsCode(inputs);
        dto.setAction(action);
        return dto;
    }

    //метод валидации DTO
    private String validateCreateOrderSite(FormFieldsDto dto) {
        String err = null;
        if (dto.getBlackBox() > 63) {
            err = "Подписной блок (в % от левого края монитора, max 63)";
        }
        return err;
    }

    //метод для синхронизации содержимого DTO с базой данных
    private void syncOrderDtoWithDB(FormFieldsDto dto) {
        OrderSite orderSite = convertDtoToOrderSite(dto);
        if (orderSite.getId() == null) {
            orderSiteDao.addOrderSite(orderSite);      //если адишник не присвоен - добавляем
        } else {
            orderSiteDao.updateOrderSite(orderSite);   //если адишник присвоен - обновляем
        }
    }

    //сохранение только созданных сайтов в БД и переход в кабинет
    @RequestMapping(value = "/save_order_site.html", method = RequestMethod.GET)
    public String saveOrderSite(HttpServletRequest req, SetPeriodDto dto, Map model) throws IOException {
        if(!isActiveUser(req)){
            return "redirect:index.html";
        }
        User user = (User) req.getSession().getAttribute("user");
        model.put("setPeriod", dto);
        FormFieldsDto orderSiteDto = (FormFieldsDto) req.getSession().getAttribute("tempOrderSiteDto");
        //задаем владельца
        req.getSession().setAttribute("tempOrderSiteDto", null);
        if (orderSiteDto != null) {
            orderSiteDto.setOwnerId(user.getId());
            OrderSite orderSite = convertDtoToOrderSite(orderSiteDto);
            orderSiteDao.addOrderSite(orderSite);
        }
        return "redirect:userhome_orders.html";
    }

    @RequestMapping(value = "/delete_order_site.html", method = RequestMethod.GET)
    public String userhomeOrders(HttpServletRequest req, @RequestParam(value = "id",
            required = true) Integer id, SetPeriodDto dto, Map model) throws IOException {
        if(!isActiveUser(req)){
            return "redirect:index.html";
        }
        model.put("setPeriod", dto);
        User user = (User) req.getSession().getAttribute("user");
        orderSiteDao.deleteOrderSiteById(id);
        return "redirect:userhome_orders.html";
    }

    //ХОСТИНГ ЗАКАЗОВ
    @RequestMapping(value = "/order-host.html", method = RequestMethod.GET)
    public String orderHost(HttpServletRequest req, Order order, @RequestParam(value = "id",
            required = false) Integer id, Map model) throws IOException {
        OrderSite site = orderSiteDao.findOrderSiteById(id);
        FormFieldsDto dto = convertOrderSiteToDto(site);
        order.setSiteId(dto.getIdSite());
        model.put("notshow", true);
        model.put("formField", dto);
        model.put("orderDto", order);
        addVisit(id, req);
        return "templ_order";
    }

    //проверка открывали ли мы сайт в этот запуск браузера, чтобы не ставить лишних визитов
    //простановка визитов в базу
    private void addVisit(Integer siteId, HttpServletRequest req) {
        Collection<Integer> visitedSites = (TreeSet<Integer>) req.getSession().getAttribute("visitedOrderSites");
        if (visitedSites == null) {
            visitedSites = new TreeSet<Integer>();
        }
        if (!visitedSites.contains(siteId)) {
            visitOrderDao.addVisit(siteId);
            visitedSites.add(siteId);
            // если сайт не посещался:добавляем в лист и пишем в сессию
            req.getSession().setAttribute("visitedOrderSites", visitedSites);
        }
    }



    // для ПОЛУЧЕНИЯ ЗАКАЗОВ
    @RequestMapping(value = "/addorder.html", method = RequestMethod.POST)
    public String editAddOrders(Order order, HttpServletRequest req, Map model) {
        orderDao.addOrder(order);
        model.put("cause", "добавлено!");
        User user = userDao.findUserByOrderSiteId(order.getSiteId());
        String email = user.getLogin();
        try {
            OrderNotification.sendOrderNotificationMail(email, order.getSiteId(), order);
        } catch (Exception e) {
            model.put("cause", "проблема с отправкой почтового сообщения");
            return "error";
        }
        model.put("message", "Благодарим Вас! В течение 5 минут с Вами свяжется наш лучший специалист");
        return "thankyou";
    }


    private OrderSite convertDtoToOrderSite(FormFieldsDto dto) {
        OrderSite site = new OrderSite();
        if (dto.getIdSite() != null) {
            site.setId(dto.getIdSite());
        }
        site.setIdTemplate(dto.getIdTemplate());
        site.setOwnerId(dto.getOwnerId());
        site.setTitleTag(dto.getTitleTag());
        site.setKeywordTag(dto.getKeywordTag());
        site.setDescripTag(dto.getDescripTag());
        site.setMainHeader(dto.getMainHeader());
        site.setBriefDef(dto.getBriefDef());
        site.setCompanyName(dto.getCompanyName());
        site.setMySite(dto.getMySite());
        site.setDopText(dto.getDopText());
        site.setMarketType(dto.getMarketType());
        site.setBgImg(dto.getBgImg());
        site.setBlackBox(dto.getBlackBox());
        site.setBtnTxt(dto.getBtnTxt());
        return site;
    }

    private FormFieldsDto convertOrderSiteToDto(OrderSite site) {
        FormFieldsDto dto = new FormFieldsDto();
        dto.setIdSite(site.getId());
        dto.setOwnerId(site.getOwnerId());
        dto.setIdTemplate(site.getIdTemplate());
        dto.setTitleTag(site.getTitleTag());
        dto.setKeywordTag(site.getKeywordTag());
        dto.setDescripTag(site.getDescripTag());
        dto.setMainHeader(site.getMainHeader());
        dto.setBriefDef(site.getBriefDef());
        dto.setCompanyName(site.getCompanyName());
        dto.setMySite(site.getMySite());
        dto.setDopText(site.getDopText());
        dto.setMarketType(site.getMarketType());
        dto.setBgImg(site.getBgImg());
        dto.setBlackBox(site.getBlackBox());
        dto.setBtnTxt(site.getBtnTxt());
        return dto;
    }

    private boolean isActiveUser(HttpServletRequest request) {
        boolean answer = false;
        HttpSession session = request.getSession();
        if (session.getAttribute("user") != null) {
            User user = (User) session.getAttribute("user");
            if (!user.getStatus().equals(User.INACTIVE)) {
                answer = true;
            }
        }
        return answer;
    }

}
